﻿using System;
using System.ComponentModel;
using System.Windows.Forms;
using ImpEx.Engine;

namespace ImpEx.GUI
{
    public partial class RequirementInstallForm : Form, IBackupRestoreUI
    {
        private RequirementInstallHandler _requirementInstallHandler;

        public RequirementInstallForm()
        {
            InitializeComponent();
        }

        #region IBackupRestoreUI Members

        public bool Show(RequiredItemCollection root, RequirementInstallHandler requirementInstall)
        {
            bool state = false;
            Invoke(new FormCallback(delegate
            {
                _requirementInstallHandler = requirementInstall;
                Visible = false;

                FillNodes(treeView1.Nodes, root);
                EnsureNextStep();

                label2.Visible = false;
                btnCancel.Enabled = true;
                state = (ShowDialog() == DialogResult.OK);
                _requirementInstallHandler = null;
            }));
            return state;
        }

        #endregion

        public static IBackupRestoreUI CreateInstance()
        {
            return new RequirementInstallForm();
        }

        public void FillNodes(TreeNodeCollection nodes, RequiredItemCollection root)
        {
            root.Sort();
            foreach (DependedItem item in root.GetRequiredItems())
            {
                TreeNode node = nodes.Add("", item.Title);
                treeView1.ImageList = imageList1;
                node.SelectedImageIndex =
                    node.ImageIndex = item.Installed.Value ? 1 : 0;
                node.Tag = item;

                UpdateNodeImage(node);

                if (item.Childs.Count > 0)
                {
                    node.Nodes.Add("", "");
                }
            }
        }

        private void EnsureNextStep()
        {
            bool state = true;
            foreach (TreeNode node in treeView1.Nodes)
            {
                DependedItem ri = (DependedItem) node.Tag;
                if (ri.RequiredState != RequiredItemState.Installed)
                {
                    state = false;
                    break;
                }
            }

            btnContinue.Enabled = state;
        }

        private void UpdateNodeState(TreeNodeCollection nodes)
        {
            foreach (TreeNode node in nodes)
            {
                UpdateNodeImage(node);
            }
        }

        private void UpdateNodeImage(TreeNode node)
        {
            if (node.Tag != null)
            {
                DependedItem di = (DependedItem) node.Tag;
                int state = 0;
                switch (di.RequiredState)
                {
                    case RequiredItemState.NotInstalled:
                        state = 0;
                        break;
                    case RequiredItemState.Installed:
                        state = 1;
                        break;
                    case RequiredItemState.ChildNotInstalled:
                        state = 3;
                        break;
                }
                node.SelectedImageIndex = node.ImageIndex = state;
                UpdateNodeState(node.Nodes);
            }
        }

        private void menuUninstallClick(object sender, EventArgs e)
        {
            InstallUninstallDependency(true);
        }

        private void InstallUninstallDependency(bool uninstall)
        {
            DependedItem di = (DependedItem) treeView1.SelectedNode.Tag;
            Cursor = Cursors.WaitCursor;
            _requirementInstallHandler(di, uninstall);
            Cursor = Cursors.Default;
            UpdateNodeState(treeView1.Nodes);
            EnsureNextStep();
        }

        private void menuInstallClick(object sender, EventArgs e)
        {
            InstallUninstallDependency(false);
        }

        private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            treeView1.SelectedNode = e.Node;
        }

        private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
        {
            DependedItem di = (DependedItem) treeView1.SelectedNode.Tag;
            menuUninstall.Enabled = (di.RequiredState != RequiredItemState.NotInstalled);
            menuInstall.Enabled = (di.RequiredState != RequiredItemState.Installed);
        }

        private void label1_Click(object sender, EventArgs e)
        {
        }

        private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            if (e.Node.Nodes.Count > 0)
            {
                DependedItem i = (DependedItem) e.Node.Tag;

                e.Node.Nodes.Clear();
                FillNodes(e.Node.Nodes, i.Childs);
            }
        }

        private void treeView1_BeforeCollapse(object sender, TreeViewCancelEventArgs e)
        {
            DependedItem item = (DependedItem) e.Node.Tag;
            e.Node.Nodes.Clear();
            if (item.Childs.Count > 0)
            {
                e.Node.Nodes.Add("", "");
            }
        }
    }
}